package com.ice.framework.common.util;

import cn.hutool.core.lang.tree.TreeNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.regex.Pattern;

/**
 * @author wangwei
 * @Date 2021/12/20 19:11
 */
public class BigDecimalUtils {

    private static Logger logger = LoggerFactory.getLogger(BigDecimalUtils.class);
    private static final Integer DEFAULT_SCALE = 2;
    public static final BigDecimal BigDecimal_100 = new BigDecimal("100");

    public BigDecimalUtils() {
    }
    
    /**
     * 判断字符串是是否符合格式
     * @Author wangwei
     * @Date 2022/6/1
     */
    public static boolean isBigDecimalMoneyFormat(Object value) {
        Pattern pattern = Pattern.compile("(^[1-9]([0-9]+)?(\\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\\.[0-9]([0-9])?$)");
        return pattern.matcher(value.toString()).matches();
    }

    public static BigDecimal getBigDecimal(Object value) {
        BigDecimal result = null;
        try {
            result = new BigDecimal(value.toString());
        } catch (Exception var3) {
            logger.error("非法参数，无法转为Bigdecimal类型");
        }

        return result;
    }

    public static BigDecimal getBigDecimal(Object value, Number defaultValue) {
        BigDecimal result = null;

        try {
            result = new BigDecimal(value.toString());
        } catch (Exception var4) {
            logger.error("非法参数，无法转为Bigdecimal类型");
            result = new BigDecimal(defaultValue.toString());
        }

        return result;
    }

    public static BigDecimal add(Number... values) {
        BigDecimal result = BigDecimal.ZERO;
        if (values != null && values.length != 0) {
            Number[] var2 = values;
            int var3 = values.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                Number value = var2[var4];
                if (value != null) {
                    result = result.add(new BigDecimal(value.toString()));
                }
            }

            return result;
        } else {
            return result;
        }
    }

    public static BigDecimal add(BigDecimal... values) {
        BigDecimal result = BigDecimal.ZERO;
        if (values != null && values.length != 0) {
            BigDecimal[] var2 = values;
            int var3 = values.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                BigDecimal value = var2[var4];
                if (value != null) {
                    result = result.add(value);
                }
            }

            return result;
        } else {
            return result;
        }
    }

    public static BigDecimal sub(Number value1, Number... value2) {
        BigDecimal result = BigDecimal.ZERO;
        if (value1 != null) {
            result = result.add(new BigDecimal(value1.toString()));
        }

        if (value2 != null && value2.length != 0) {
            Number[] var3 = value2;
            int var4 = value2.length;

            for (int var5 = 0; var5 < var4; ++var5) {
                Number value = var3[var5];
                if (value != null) {
                    result = result.subtract(new BigDecimal(value.toString()));
                }
            }

            return result;
        } else {
            return result;
        }
    }

    public static BigDecimal sub(BigDecimal value1, BigDecimal... value2) {
        BigDecimal result = BigDecimal.ZERO;
        if (value1 != null) {
            result = result.add(value1);
        }

        if (value2 != null && value2.length != 0) {
            BigDecimal[] var3 = value2;
            int var4 = value2.length;

            for (int var5 = 0; var5 < var4; ++var5) {
                BigDecimal value = var3[var5];
                if (value != null) {
                    result = result.subtract(value);
                }
            }

            return result;
        } else {
            return result;
        }
    }

    public static BigDecimal mul(Number... values) {
        if (values != null && values.length != 0) {
            BigDecimal result = BigDecimal.ONE;
            Number[] var2 = values;
            int var3 = values.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                Number value = var2[var4];
                if (value != null) {
                    result = result.multiply(new BigDecimal(value.toString()));
                }
            }

            return result;
        } else {
            return null;
        }
    }

    public static BigDecimal mul(BigDecimal... values) {
        if (values != null && values.length != 0) {
            BigDecimal result = BigDecimal.ONE;
            BigDecimal[] var2 = values;
            int var3 = values.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                BigDecimal value = var2[var4];
                if (value != null) {
                    result = result.multiply(value);
                }
            }

            return result;
        } else {
            return null;
        }
    }

    public static BigDecimal div(Number dividend, Number divisor) {
        return div(dividend, divisor, DEFAULT_SCALE);
    }

    public static BigDecimal div(BigDecimal dividend, BigDecimal divisor) {
        return div(dividend, divisor, DEFAULT_SCALE);
    }

    public static BigDecimal div(Number dividend, Number divisor, Integer scale) {
        if (dividend == null) {
            return null;
        } else if (divisor != null && divisor.doubleValue() != 0.0D) {
            if (scale == null) {
                scale = DEFAULT_SCALE;
            }

            if (scale < 0) {
                throw new IllegalArgumentException("The scale must be a positive integer or zero");
            } else {
                BigDecimal b1 = new BigDecimal(dividend.toString());
                BigDecimal b2 = new BigDecimal(divisor.toString());
                return b1.divide(b2, scale, 4);
            }
        } else {
            throw new IllegalArgumentException("The divisor cannot be zero or null !");
        }
    }

    public static BigDecimal div(BigDecimal dividend, BigDecimal divisor, Integer scale) {
        if (dividend == null) {
            return null;
        } else if (divisor != null && divisor.doubleValue() != 0.0D) {
            if (scale == null) {
                scale = DEFAULT_SCALE;
            }

            if (scale < 0) {
                throw new IllegalArgumentException("The scale must be a positive integer or zero");
            } else {
                return dividend.divide(divisor, scale, 4);
            }
        } else {
            throw new IllegalArgumentException("The divisor cannot be zero or null !");
        }
    }

    public static BigDecimal round(Number value) {
        return round(value, DEFAULT_SCALE);
    }

    public static BigDecimal round(BigDecimal value) {
        return round(value, DEFAULT_SCALE);
    }

    public static BigDecimal round(BigDecimal value, Integer scale) {
        if (value == null) {
            return null;
        } else {
            if (scale == null) {
                scale = DEFAULT_SCALE;
            }

            if (scale < 0) {
                throw new IllegalArgumentException("The scale must be a positive integer or zero");
            } else {
                return value.setScale(scale, 4);
            }
        }
    }

    public static BigDecimal round(Number value, Integer scale) {
        if (value == null) {
            return null;
        } else {
            if (scale == null) {
                scale = DEFAULT_SCALE;
            }

            if (scale < 0) {
                throw new IllegalArgumentException("The scale must be a positive integer or zero");
            } else {
                BigDecimal b = new BigDecimal(value.toString());
                return b.divide(BigDecimal.ONE, scale, 4);
            }
        }
    }

    public static String format(BigDecimal value) {
        if (value == null) {
            throw new IllegalArgumentException("The value must be a valid value.");
        } else {
            DecimalFormat df = new DecimalFormat(".00");
            return df.format(value);
        }
    }

    public static BigDecimal min(Object a, Object b) {
        BigDecimal i = new BigDecimal(String.valueOf(a));
        BigDecimal j = new BigDecimal(String.valueOf(b));
        return i.compareTo(j) < 0 ? i : j;
    }

    public static BigDecimal min(BigDecimal a, BigDecimal b) {
        return a.compareTo(b) < 0 ? a : b;
    }

    public static BigDecimal max(BigDecimal a, BigDecimal b) {
        return a.compareTo(b) > 0 ? a : b;
    }

    public static BigDecimal toPercent(BigDecimal a) {
        return a.divide(new BigDecimal("100"));
    }

    public static BigDecimal transNullToZERO(BigDecimal a) {
        return a == null ? BigDecimal.ZERO : a;
    }

    public static BigDecimal transNullStringToZERO(String a) {
        return StringUtils.isEmpty(a) ? BigDecimal.ZERO : new BigDecimal(a.trim());
    }

    public static BigDecimal transMinusToZERO(BigDecimal a) {
        return a.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : a;
    }

    public static BigDecimal getExactBigDicimal(double num) {
        String numStr = num + "";
        return new BigDecimal(numStr);
    }

    public static boolean isNotPlus(BigDecimal number) {
        if (number == null) {
            return true;
        } else {
            return number.compareTo(new BigDecimal(0)) <= 0;
        }
    }

    public static boolean isGreaterZero(BigDecimal number) {
        if (number == null) {
            return false;
        } else {
            return number.compareTo(new BigDecimal(0)) > 0;
        }
    }

    public static BigDecimal convertBigDecimal(BigDecimal num) {
        if (num == null) {
            num = new BigDecimal(0);
        }

        return num;
    }

    public static Integer convertInteger(Integer integer) {
        if (integer == null) {
            integer = new Integer(0);
        }

        return integer;
    }

    public static BigDecimal convertBigDecimal(BigDecimal num, BigDecimal bd) {
        return num == null ? bd : num;
    }

    public static String covertBigDecimalToString(BigDecimal num) {
        return num == null ? "" : num.toString();
    }

    public static double toDouble(BigDecimal num) {
        return num == null ? 0.0D : num.doubleValue();
    }

    public static boolean compareBigDecimalMinus(BigDecimal bd1, BigDecimal bd2) {
        boolean returnFlag = false;
        int i1 = bd1.compareTo(bd2);
        if (i1 < 0) {
            returnFlag = true;
        }

        return returnFlag;
    }

    public static boolean compareBigDecimalMinusEq(BigDecimal bd1, BigDecimal bd2) {
        boolean returnFlag = false;
        int i1 = bd1.compareTo(bd2);
        if (i1 < 0 || i1 == 0) {
            returnFlag = true;
        }

        return returnFlag;
    }

    public static boolean compareBigDecimalPlus(BigDecimal bd1, BigDecimal bd2) {
        boolean returnFlag = false;
        int i1 = bd1.compareTo(bd2);
        if (i1 > 0) {
            returnFlag = true;
        }

        return returnFlag;
    }

    public static boolean isNullBigDecimal(BigDecimal bigDecimal) {
        boolean result = false;
        if (bigDecimal == null) {
            result = true;
        }

        return result;
    }

    public static boolean isGreaterOrEqualToZero(BigDecimal bigDecimal) {
        boolean result = false;
        if (isNullBigDecimal(bigDecimal)) {
            return result;
        } else {
            if (bigDecimal.compareTo(BigDecimal.ZERO) >= 0) {
                result = true;
            }

            return result;
        }
    }

    public static BigDecimal transZEROToONE(BigDecimal bigDecimal) {
        return BigDecimal.ZERO.compareTo(bigDecimal) == 0 ? BigDecimal.ONE : bigDecimal;
    }

    public static boolean isEqual(BigDecimal one, BigDecimal two) {
        return one.compareTo(two) == 0;
    }

    public static BigDecimal roundBigDecimal(BigDecimal one, int size) {
        return one.setScale(size, 4);
    }
}
